package com.example.mannortycoon.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.Update;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mannortycoon.dao.UserSeedDao;
import com.example.mannortycoon.entity.*;
import com.example.mannortycoon.service.*;
import com.example.mannortycoon.uitl.PageUtils;
import com.example.mannortycoon.uitl.Query;
import com.example.mannortycoon.uitl.R;
import com.example.mannortycoon.vo.UserSeedVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


@Service("userSeedService")
public class UserSeedServiceImpl extends ServiceImpl<UserSeedDao, UserSeedEntity> implements UserSeedService {

    private final UserService userService;

    private final SeedService seedService;

    private final SeedUnlockConditionsService seedUnlockConditionsService;

    private final UserCropService userCropService;

    @Autowired
    public UserSeedServiceImpl(UserService userService, SeedService seedService,
                               SeedUnlockConditionsService seedUnlockConditionsService,
                               UserCropService userCropService){
        this.userService = userService;
        this.seedService = seedService;
        this.seedUnlockConditionsService = seedUnlockConditionsService;
        this.userCropService = userCropService;
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<UserSeedEntity> page = this.page(
                new Query<UserSeedEntity>().getPage(params),
                new QueryWrapper<>()
        );

        return new PageUtils(page);
    }

    @Override
    @Transactional
    public R save(UserBuySeedRecordEntity userBuySeedRecordEntity) {
        Long userId = userBuySeedRecordEntity.getUserId();
        Integer number = userBuySeedRecordEntity.getNumber();
        Long seedId = userBuySeedRecordEntity.getSeedId();
        //查询用户
        UserEntity userEntity = userService.getById(userId);

        //查询种子
        SeedEntity seedEntity = seedService.getById(userBuySeedRecordEntity.getSeedId());
        if(seedEntity == null){
            return R.error("种子不存在");
        }
        Double totalPrice = number * seedEntity.getSeedPrice();
        //判断用户种子币是否足够
        if(userEntity.getSeedGold() < totalPrice){
            return R.error("种子币不足");
        }
        //查询用户是否拥有该种子
        QueryWrapper<UserSeedEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId).eq("seed_id",seedId);
        UserSeedEntity userSeedEntity = this.getOne(wrapper);
        if(userSeedEntity == null){
            userSeedEntity = new UserSeedEntity();
            userSeedEntity.setUserId(userId);
            userSeedEntity.setCreateTime(new Date());
            userSeedEntity.setNumber(number);
            userSeedEntity.setSeedId(seedId);
            this.save(userSeedEntity);
        }else{
            userSeedEntity.setNumber(userSeedEntity.getNumber() + number);
            userSeedEntity.setUpdateTime(new Date());
            this.updateById(userSeedEntity);
        }
        //减少用户种子币数量
        userEntity.setSeedGold(userEntity.getSeedGold() - totalPrice);
        userService.updateById(userEntity);
        return R.ok();
    }

    @Override
    public List<UserSeedVo> getUserSeedList(Long userId) {
        QueryWrapper<UserSeedEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId);
        List<UserSeedEntity> list = this.list(wrapper);
        return list.stream().map(item->{
            UserSeedVo userSeedVo = new UserSeedVo();
            userSeedVo.setSeedId(item.getSeedId());
            userSeedVo.setNumber(item.getNumber());
            SeedEntity seedEntity= seedService.getById(item.getSeedId());
            if(seedEntity != null){
                userSeedVo.setSeedName(seedEntity.getSeedName());
                userSeedVo.setSeedImgUrl(seedEntity.getSeedImgUrl());
            }
            return userSeedVo;
        }).collect(Collectors.toList());

    }

    @Override
    @Transactional
    public void saveUserSeedList(Long userId,List<UserSeedEntity> userSeedList) {
        UpdateWrapper<UserSeedEntity> wrapper = new UpdateWrapper<>();
        wrapper.eq("user_id",userId);
        this.remove(wrapper);
        if(userSeedList.size() > 0){
            List<UserSeedEntity> collect = userSeedList.stream().peek(item -> {
                item.setCreateTime(new Date());
                item.setUpdateTime(new Date());
            }).collect(Collectors.toList());
            this.saveOrUpdateBatch(collect);
        }
    }

    @Override
    public R unlockSeed(Long userId, Long seedId) {
        //获取种子解锁条件
        QueryWrapper<SeedUnlockConditionsEntity> seedUnlockConditionsEntityQueryWrapper = new QueryWrapper<>();
        seedUnlockConditionsEntityQueryWrapper.eq("seed_id", seedId);
        List<SeedUnlockConditionsEntity> unlockConditionsEntityList = seedUnlockConditionsService.list(seedUnlockConditionsEntityQueryWrapper);
        //转换为作物id集合
        List<Long> collect = unlockConditionsEntityList.stream().map(SeedUnlockConditionsEntity::getCropId).collect(Collectors.toList());
        //查询用户作物数量
        QueryWrapper<UserCropEntity> userCropEntityQueryWrapper = new QueryWrapper<>();
        userCropEntityQueryWrapper.eq("user_id",userId).in("crop_id",collect);
        List<UserCropEntity> list = userCropService.list(userCropEntityQueryWrapper);
        List<UserCropEntity> newList = this.unlockSeed(list,unlockConditionsEntityList);
        if(newList == null){
            return R.error("对应的作物不足");
        }
        //更新用户作物数量
        userCropService.updateBatchById(newList);

        //新增用户种子，设置数量为0
        UserSeedEntity userSeedEntity = new UserSeedEntity();
        userSeedEntity.setUserId(userId);
        userSeedEntity.setSeedId(seedId);
        userSeedEntity.setCreateTime(new Date());
        this.save(userSeedEntity);
        return R.ok("解锁成功");
    }

    @Override
    @Transactional
    public R sellSeed(Long userId, Long seedId, Integer number) {
        //获取用户种子信息
        QueryWrapper<UserSeedEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId).eq("seed_id",seedId);
        UserSeedEntity userSeedEntity = this.getOne(wrapper);
        if(userSeedEntity == null || userSeedEntity.getNumber() < number){
            return R.error("用户种子数量不足");
        }
        //获取种子信息
        SeedEntity seedEntity = seedService.getById(seedId);
        if(seedEntity == null){
            return R.error("种子不存在");
        }
        //获取用户信息
        UserEntity userEntity = userService.getById(userId);
        if(userEntity == null){
            return R.error("用户不存在");
        }
        //添加用户种子币
        userEntity.setSeedGold(userEntity.getSeedGold() + number * seedEntity.getSeedPrice() / 2);
        userService.updateById(userEntity);
        //减少用户种子数量
        userSeedEntity.setNumber(userSeedEntity.getNumber() - number);
        this.updateById(userSeedEntity);
        return R.ok();
    }

    @Override
    public boolean has(Long userId, Long seedId) {
        QueryWrapper<UserSeedEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId).eq("seed_id",seedId);
        return this.getOne(wrapper) != null;
    }

    private List<UserCropEntity> unlockSeed(List<UserCropEntity> list, List<SeedUnlockConditionsEntity> unlockConditionsEntityList) {
        if(list.size() < unlockConditionsEntityList.size()){
            return null;
        }
        //将list装入set中
        Map<Long,UserCropEntity> userCropMap = new HashMap<>();
        list.forEach(item-> userCropMap.put(item.getCropId(),item));

        for (SeedUnlockConditionsEntity seedUnlockConditionsEntity : unlockConditionsEntityList) {
            UserCropEntity userCropEntity = userCropMap.get(seedUnlockConditionsEntity.getCropId());
            if(userCropEntity == null || userCropEntity.getNumber() < seedUnlockConditionsEntity.getNumber()){
                return null;
            }
            userCropEntity.setNumber(userCropEntity.getNumber()-seedUnlockConditionsEntity.getNumber());
        }
        return list;
    }
}